package com.example.custsecurity.security.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.custsecurity.security.filter.CustLoginJWTTokenFilter;
import com.example.custsecurity.security.filter.VerifyJWTTokenFilter;
import com.example.custsecurity.security.jwt.CustJwtService;
import com.example.custsecurity.security.servic.CustUserDetailsServic;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/*
 * security功能：
 * 授权：authorization
 * 认证：authentication
 * 过滤链：filter
 * 会话管理：session managment
 * */

@Slf4j
@Configuration
public class CustSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustAccessDeniedHandler custAccessDeniedHandler;

    @Autowired
    private CustAuthenticationEntryPoint custAuthenticationEntryPoint;

    @Autowired
    private CustFailureHandler custFailureHandler;

    @Autowired
    private CustSuccessfulHandler custSuccessfulHandler;

    @Autowired
    private CustUserDetailsServic custUserDetailsServic;

    @Autowired
    private CustPasswordEncoder custPasswordEncoder;

    @Autowired
    private CustJwtService custJwtService;

    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
//        基于内存方式的认证
//        InMemoryUserDetailsManagerConfigurer config = builder.inMemoryAuthentication();
//        创建用户与密码及对应的角色

        /*builder.inMemoryAuthentication()
                .withUser("admin").password("123").authorities("ADMIN")
                .and()
                .withUser("sys").password("456").authorities("SYS");
        */

        builder
                .userDetailsService(custUserDetailsServic)   //从数据库取出对应用户名的相关信息
                .passwordEncoder(custPasswordEncoder);     //调用密码加密器 对输入的密码进行加密 注：数据库中保存的用户密码使用的加密方式一定要和加密器中使用的算法保持一致

        super.configure(builder);
    }

//    该方法主要负责权限控制
//    权限小的放在前面
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        过滤器,在登陆的时候执行一次
        CustLoginJWTTokenFilter custLoginJWTTokenFilter = new CustLoginJWTTokenFilter(custJwtService,this.authenticationManager());
//        设置认证成功的处理请求
        custLoginJWTTokenFilter.setAuthenticationSuccessHandler(custSuccessfulHandler);
//        设置认证失败的处理请求
        custLoginJWTTokenFilter.setAuthenticationFailureHandler(custFailureHandler);

        http.csrf().disable()
                .authorizeRequests()
//                .antMatchers("/**").permitAll()         //允许所有的请求都能访问
//                .antMatchers("/**").authenticated()     //登录成功后可以访问所有请求路径
                .antMatchers("/smile").anonymous()  //匿名用户可以访问
//                .antMatchers("/test.html","/login","/logprocess").permitAll()   //所有用户可以访问
                .antMatchers("/say","/cry")
                .hasAuthority("SYS")
                .antMatchers("/talk","/jump")
                .hasAuthority("ADMIN")

                .and()
                .formLogin()                     //如未自定义登录页面，调用spring boot自带的登录页面
                .loginPage("/")       //自定义登录页面
                .loginProcessingUrl("/logingprocess")
//                .successHandler(custSuccessfulHandler)   //认证成功
//                .failureHandler(custFailureHandler)  //输入错误的账号与密码
                .and()
                .exceptionHandling()
                .accessDeniedHandler(custAccessDeniedHandler) //超越权限被拒绝访问
                .authenticationEntryPoint(custAuthenticationEntryPoint)    //异常处理  匿名用户访问未授权的资源(请求路径)

                .and()
                .addFilter(custLoginJWTTokenFilter)    //添加自定义过滤器,用于登录认证
                .addFilter(new VerifyJWTTokenFilter(this.custJwtService,this.authenticationManager())); //添加自定义过滤器,用于每次请求的过滤器
//                .defaultSuccessUrl("/cry",true);      //设置登陆成功后默认跳转的位置


//        super.configure(http);
    }

//    创建用户登陆密码  加密器
//    @Bean
//    public PasswordEncoder passwordEncoder(){
//        return NoOpPasswordEncoder.getInstance();
//    }
}


